package ru.compscicenter.databases.zaikina.nodes;

import ru.compscicenter.databases.zaikina.common.DatabaseController;
import ru.compscicenter.databases.zaikina.common.NodeProcessor;
import ru.compscicenter.databases.zaikina.common.model.Node;
import ru.compscicenter.databases.zaikina.common.model.NodeConfig;
import ru.compscicenter.databases.zaikina.common.model.NodeType;
import ru.compscicenter.databases.zaikina.httpserver.HttpSocketProcessor;

import java.io.File;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class NodeMain {
    private static DatabaseController controller;
    public static NodeConfig config;
    public static Node node;


    private static void createDirectory(Integer nodeId) {
        File file = new File(nodeId.toString());
        if (!file.exists() || !file.isDirectory()) {
            file.mkdir();
        }
    }

    private static DatabaseController initController(Node node) {
        createDirectory(node.getNodeId());
        if (node.getType() == NodeType.FileStorage) {
            FilesNode filesNode = new FilesNode(config, node.getNodeId());
            filesNode.load();
            return new DatabaseController(filesNode);
        }
        if (node.getType() == NodeType.VocabularyNode) {
            return new DatabaseController(new VocabularyNode(node.getNodeId()));
        }
        return null;
    }

    private static void loop() throws IOException {
        ServerSocket ss = new ServerSocket(node.getPort());
        while (true) {
            Socket s = ss.accept();
            System.err.println("Client accepted on port = " + node.getPort());
            if (node.getType() == NodeType.HttpServer) {
                new Thread(new HttpSocketProcessor(s, config)).start();
            } else {
                new Thread(new NodeProcessor(s, controller)).start();
            }
        }
    }

    public static void main(String[] args) {
        if (args.length != 1) {
            System.out.println("Enter node id");
            return;
        }

        Integer id = Integer.parseInt(args[0]);
        try {
            config = NodeConfig.load();
        } catch (IOException ex) {
            System.out.println(id + ": Can not load config.txt life. Aborted");
            return;
        }

        node = config.getNodeById(id);
        System.out.println("Node id: " + node.getNodeId());

        if (node.getType() != NodeType.HttpServer) {
            controller = initController(node);
        }

        if (controller != null || node.getType() == NodeType.HttpServer) {
            try {
                loop();
            } catch (IOException ex) {
                ex.printStackTrace();
                System.out.println(id + ": Aborted.");
            }
        }
    }

}
